#ifndef _SHARED_HRPTR_H_
#define _SHARED_HRPTR_H_

namespace Hiranipra {

	template <class T> class hrptr
	{
	public:
		explicit hrptr( T* p = 0 )
			: _counter( 0 )
		{
			if( p != NULL )
				_counter = new counter( p );
		}

		hrptr( const hrptr& r ) throw()
		{
			this->Retain( r._counter );
		}

		~hrptr()
		{
			this->Release();
		}

		hrptr& operator = ( const hrptr& r )
		{
			if( this != &r )
			{
				this->Release();
				this->Retain( r._counter );
			}
			return *this;
		}

		T& operator * ()  const throw()
		{
			return *_counter->ptr;
		}
		T* operator -> () const throw()
		{
			return _counter->ptr;
		}
		T* GetValue() const throw()
		{
			return _counter ? _counter->ptr : 0;
		}
		bool IsUnique()   const throw()
		{
			return ( _counter ? _counter->count == 1 : true );
		}

	private:

		struct counter {
			counter( T* p = 0, uint32 c = 1 ) :
				ptr( p ), count( c )
			{
			}

			T*			ptr;
			uint32		count;
		}* _counter;

		void Retain( counter* c ) throw()
		{
			_counter = c;
			if( _counter != NULL )
				_counter->count++;
		}

		void Release()
		{
			if( _counter != NULL )
			{
				if( --_counter->count == 0 )
				{
					DELETE_PTR( _counter->ptr );
					DELETE_PTR( _counter );
				}
				_counter = NULL;
			}
		}
	};

}

#endif // _SHARED_HRPTR_H_
